<template>
    <a-flex wrap="wrap" gap="small" class="f api_info">
        <div class="left_kuang">
            <div class="button_row f_row">
                <a-select
                    v-model:value="state.api.method"
                    style="width: 100px"
                    placeholder="请选择"
                    @change="changeEnv()"
                >
                    <a-select-option value="GET">GET</a-select-option>
                    <a-select-option value="POST">POST</a-select-option>
                    <a-select-option value="PUT">PUT</a-select-option>
                    <a-select-option value="DELETE">DELETE</a-select-option>
                </a-select>
                <a-select
                    v-model:value="state.env"
                    style="width: 140px"
                    placeholder="请选择"
                    @change="getEnv"
                    :options="state.item?.env?.all"
                ></a-select>

                <a-select
                    v-if="state.item.tag?.length > 0"
                    v-model:value="state.api.tag"
                    style="width: 160px"
                    placeholder="暂无标签，请选择"
                    :max-tag-count="1"
                    mode="multiple"
                    :maxTagTextLength="4"
                    @change="saveApi"
                    ><a-select-option v-for="t in state.item.tag" :value="t.key" :label="t.name">
                        <a-tag :color="t.color">{{ t.name }}</a-tag>
                    </a-select-option>
                </a-select>
                <!-- <a-tooltip title="刷新" color="var(--Primary-2)">
                    <a-button shape="circle" type="text" :icon="h(Refresh)" @click="refreshItem" />
                </a-tooltip> -->
                <div style="flex: 1"></div>
                <a-button type="primary" @click="sendApi" :loading="state.loading">发送</a-button>
                <!-- <a-button class="f_row" style="gap: 4px"
                    >保存
                    <a-tooltip placement="bottom" color="var(--Primary-2)">
                        <template #title>仅接口参数，无请求值，无环境值</template>
                        <info theme="outline" size="14" fill="var(--character-60)" />
                    </a-tooltip>
                </a-button> -->

                <a-button class="f_row" style="gap: 4px"
                    >保存为场景
                    <a-tooltip placement="bottom" color="var(--Primary-2)">
                        <template #title>将本次请求的所有参数和值保存为快照</template>
                        <info theme="outline" size="14" />
                    </a-tooltip>
                </a-button>
            </div>
            <div class="path f_row">
                <a-textarea
                    v-model:value="state.api.url"
                    placeholder="请输入路径"
                    :auto-size="{ minRows: 1, maxRows: 5 }"
                    class="path_input"
                />
            </div>
            <div class="ppp">
                <a-segmented v-model:value="state.params.select" :options="state.params.options" block />
            </div>
            <div class="f_col ppp2" ref="ppp2Ref" style="height: calc(100% - 150px); width: 100%">
                <template v-if="state.params.select == 'params'">
                    <a-table
                        bordered
                        :scroll="{ y: state.ppp2, x: false }"
                        :data-source="state.api.params"
                        :pagination="false"
                        class="wh100"
                        size="small"
                        :columns="paramsColumns"
                        :row-selection="{
                            selectedRowKeys: state.params.pSelectedRowKeys,
                            onChange: onSelectChange,
                            getCheckboxProps: (record) => {
                                return {
                                    disabled: record.isInner,
                                }
                            },
                        }"
                    >
                        <template #bodyCell="{ column, text, record }">
                            <template v-if="column.dataIndex == 'name'">
                                <a-input
                                    v-model:value="record.name"
                                    @change="changeparams('name', record)"
                                    placeholder="添加参数"
                                    :status="record.name.trim() == '' && !record.isInner ? 'error' : ''"
                                >
                                </a-input>
                            </template>
                            <template v-else-if="column.dataIndex == 'value'">
                                <a-input
                                    v-model:value="record.value"
                                    @change="changeparams('value', record)"
                                    placeholder="添加参数值"
                                    :disabled="record.isInner"
                                >
                                    <template #suffix v-if="!record.isInner">
                                        <div class="f_row" style="gap: 8px">
                                            <a-tooltip placement="bottom" color="var(--Primary-2)">
                                                <template #title>智能数据</template>
                                                <magic
                                                    theme="outline"
                                                    size="14"
                                                    class="mouse-pointer"
                                                    fill="var(--character-60)"
                                                />
                                            </a-tooltip>

                                            <a-tooltip placement="bottom" color="var(--Primary-2)">
                                                <template #title>放大展示</template>
                                                <stretching
                                                    theme="outline"
                                                    size="14"
                                                    class="mouse-pointer"
                                                    fill="var(--character-60)"
                                                />
                                            </a-tooltip>
                                        </div>
                                    </template>
                                </a-input>
                            </template>
                            <template v-else-if="column.dataIndex == 'desc'">
                                <a-input
                                    v-model:value="record.desc"
                                    @change="changeparams('desc', record)"
                                    placeholder="说明"
                                    :disabled="record.isInner"
                                >
                                    <template #suffix v-if="!record.isInner">
                                        <div class="f_row" style="gap: 8px">
                                            <a-tooltip placement="bottom" color="var(--Primary-2)">
                                                <template #title>放大展示</template>
                                                <stretching
                                                    theme="outline"
                                                    size="14"
                                                    class="mouse-pointer"
                                                    fill="var(--character-60)"
                                                />
                                            </a-tooltip>
                                        </div> </template
                                ></a-input>
                            </template>
                            <template v-else-if="column.dataIndex == 'opt'">
                                <a-popconfirm
                                    title="确认删除吗？"
                                    ok-text="是"
                                    cancel-text="否"
                                    v-if="!record.isInner && !record.global"
                                    @confirm="changeparams('delete', record)"
                                >
                                    <a-button type="link" size="small">删除</a-button>
                                </a-popconfirm>
                                <a-tooltip
                                    placement="bottom"
                                    color="var(--Primary-2)"
                                    v-if="!record.isInner && record.global"
                                >
                                    <template #title>全局参数，无法删除，只能不启用</template>
                                    <a-button type="link" size="small" :disabled="true">全局</a-button>
                                </a-tooltip>
                            </template>
                            <template v-else-if="column.dataIndex == 'isMust'">
                                <a-checkbox
                                    v-model:checked="record.isMust"
                                    :disabled="record.isInner"
                                    @change="changeparams('isMust', record)"
                                />
                            </template>
                            <template v-else-if="column.dataIndex == 'isEncode'">
                                <a-checkbox
                                    v-model:checked="record.isEncode"
                                    :disabled="record.isInner"
                                    @change="changeparams('isEncode', record)"
                                />
                            </template>
                        </template>
                    </a-table>
                </template>
                <template v-if="state.params.select == 'headers'">
                    <a-table
                        bordered
                        :scroll="{ y: state.ppp2 }"
                        :data-source="state.api.headers"
                        :pagination="false"
                        class="wh100"
                        size="small"
                        :columns="headersColumns"
                        :row-selection="{
                            selectedRowKeys: state.params.hSelectedRowKeys,
                            onChange: onSelectHeadersChange,
                            getCheckboxProps: (record) => {
                                return {
                                    disabled: record.isInner,
                                }
                            },
                        }"
                    >
                        <template #bodyCell="{ column, text, record }">
                            <template v-if="column.dataIndex == 'name'">
                                <a-input
                                    v-model:value="record.name"
                                    @change="changeHeaders('name', record)"
                                    placeholder="添加请求头参数"
                                    :status="record.name.trim() == '' && !record.isInner ? 'error' : ''"
                                >
                                </a-input>
                            </template>
                            <template v-else-if="column.dataIndex == 'value'">
                                <a-input
                                    v-model:value="record.value"
                                    @change="changeHeaders('value', record)"
                                    placeholder="添加请求头值"
                                    :disabled="record.isInner"
                                >
                                    <template #suffix v-if="!record.isInner">
                                        <div class="f_row" style="gap: 8px">
                                            <a-tooltip placement="bottom" color="var(--Primary-2)">
                                                <template #title>放大展示</template>
                                                <stretching
                                                    theme="outline"
                                                    size="14"
                                                    class="mouse-pointer"
                                                    fill="var(--character-60)"
                                                />
                                            </a-tooltip>
                                        </div>
                                    </template>
                                </a-input>
                            </template>
                            <template v-else-if="column.dataIndex == 'desc'">
                                <a-input
                                    v-model:value="record.desc"
                                    @change="changeHeaders('desc', record)"
                                    placeholder="说明"
                                    :disabled="record.isInner"
                                >
                                    <template #suffix v-if="!record.isInner">
                                        <div class="f_row" style="gap: 8px">
                                            <a-tooltip placement="bottom" color="var(--Primary-2)">
                                                <template #title>放大展示</template>
                                                <stretching
                                                    theme="outline"
                                                    size="14"
                                                    class="mouse-pointer"
                                                    fill="var(--character-60)"
                                                />
                                            </a-tooltip>
                                        </div> </template
                                ></a-input>
                            </template>
                            <template v-else-if="column.dataIndex == 'opt'">
                                <a-popconfirm
                                    title="确认删除吗？"
                                    ok-text="是"
                                    cancel-text="否"
                                    v-if="!record.isInner && !record.global"
                                    @confirm="changeHeaders('delete', record)"
                                >
                                    <a-button type="link" size="small">删除</a-button>
                                </a-popconfirm>
                                <a-tooltip
                                    placement="bottom"
                                    color="var(--Primary-2)"
                                    v-if="!record.isInner && record.global"
                                >
                                    <template #title>全局参数，无法删除，只能不启用</template>
                                    <a-button type="link" size="small" :disabled="true">全局</a-button>
                                </a-tooltip>
                            </template>
                        </template>
                    </a-table>
                </template>
                <div v-if="state.params.select == 'body'" class="wh100">
                    <div v-if="state.api.method == 'GET'" class="f wh100">GET不支持BODY</div>
                    <template v-else>
                        <a-segmented
                            v-model:value="state.api.body.select"
                            :options="state.body.options"
                            block
                            @change="changeBodyType"
                            class="bodySegmented"
                        />
                        <div class="f wh100" style="height: calc(100% - 28px)">
                            <template v-if="state.api.body.select == '无'"> 无BODY体 </template>
                            <template v-else-if="state.api.body.select == 'json'">
                                <json-editor-vue
                                    class="editor wh100"
                                    v-model="state.api.body.json"
                                    @change="saveApi()"
                                    :language="'zh-CN'"
                                    :modeList="['code', 'text', 'view']"
                                />
                            </template>
                            <template
                                v-else-if="
                                    state.api.body.select == 'form-data' ||
                                    state.api.body.select == 'x-www-form-urlencoded'
                                "
                            >
                                <a-table
                                    bordered
                                    :scroll="{ y: state.ppp2 - 29 }"
                                    :data-source="state.api.body.form"
                                    :pagination="false"
                                    class="wh100"
                                    size="small"
                                    :columns="paramsColumns"
                                    :row-selection="{
                                        selectedRowKeys: state.params.bSelectedRowKeys,
                                        onChange: onSelectBodyChange,
                                        getCheckboxProps: (record) => {
                                            return {
                                                disabled: record.isInner,
                                            }
                                        },
                                    }"
                                >
                                    <template #bodyCell="{ column, text, record }">
                                        <template v-if="column.dataIndex == 'name'">
                                            <a-input
                                                v-model:value="record.name"
                                                @change="changeBody('name', record)"
                                                placeholder="添加参数"
                                                :status="record.name.trim() == '' && !record.isInner ? 'error' : ''"
                                            >
                                            </a-input>
                                        </template>
                                        <template v-else-if="column.dataIndex == 'value'">
                                            <a-input
                                                v-model:value="record.value"
                                                @change="changeBody('value', record)"
                                                placeholder="添加参数值"
                                                :disabled="record.isInner"
                                            >
                                                <template #suffix v-if="!record.isInner">
                                                    <div class="f_row" style="gap: 8px">
                                                        <a-tooltip placement="bottom" color="var(--Primary-2)">
                                                            <template #title>智能数据</template>
                                                            <magic
                                                                theme="outline"
                                                                size="14"
                                                                class="mouse-pointer"
                                                                fill="var(--character-60)"
                                                            />
                                                        </a-tooltip>

                                                        <a-tooltip placement="bottom" color="var(--Primary-2)">
                                                            <template #title>放大展示</template>
                                                            <stretching
                                                                theme="outline"
                                                                size="14"
                                                                class="mouse-pointer"
                                                                fill="var(--character-60)"
                                                            />
                                                        </a-tooltip>
                                                    </div>
                                                </template>
                                            </a-input>
                                        </template>
                                        <template v-else-if="column.dataIndex == 'desc'">
                                            <a-input
                                                v-model:value="record.desc"
                                                @change="changeBody('desc', record)"
                                                placeholder="说明"
                                                :disabled="record.isInner"
                                            >
                                                <template #suffix v-if="!record.isInner">
                                                    <div class="f_row" style="gap: 8px">
                                                        <a-tooltip placement="bottom" color="var(--Primary-2)">
                                                            <template #title>放大展示</template>
                                                            <stretching
                                                                theme="outline"
                                                                size="14"
                                                                class="mouse-pointer"
                                                                fill="var(--character-60)"
                                                            />
                                                        </a-tooltip>
                                                    </div> </template
                                            ></a-input>
                                        </template>
                                        <template v-else-if="column.dataIndex == 'opt'">
                                            <a-popconfirm
                                                title="确认删除吗？"
                                                ok-text="是"
                                                cancel-text="否"
                                                v-if="!record.isInner && !record.global"
                                                @confirm="changeBody('delete', record)"
                                            >
                                                <a-button type="link" size="small">删除</a-button>
                                            </a-popconfirm>
                                            <a-tooltip
                                                placement="bottom"
                                                color="var(--Primary-2)"
                                                v-if="!record.isInner && record.global"
                                            >
                                                <template #title>全局参数，无法删除，只能不启用</template>
                                                <a-button type="link" size="small" :disabled="true">全局</a-button>
                                            </a-tooltip>
                                        </template>
                                        <template v-else-if="column.dataIndex == 'isMust'">
                                            <a-checkbox
                                                v-model:checked="record.isMust"
                                                :disabled="record.isInner"
                                                @change="changeBody('isMust', record)"
                                            />
                                        </template>
                                        <template v-else-if="column.dataIndex == 'isEncode'">
                                            <a-checkbox
                                                v-model:checked="record.isEncode"
                                                :disabled="record.isInner"
                                                @change="changeBody('isEncode', record)"
                                            />
                                        </template>
                                    </template>
                                </a-table>
                            </template>
                            <template v-else-if="state.api.body.select == '自定义'">
                                <a-textarea
                                    v-model:value="state.api.body.text"
                                    style="height: 100%; resize: none"
                                    placeholder="请输入自定义BODY"
                                />
                            </template>
                        </div>
                    </template>
                </div>
                <div v-if="state.params.select == '前置配置'" class="wh100">
                    <codeM
                        :value="state.api.before[0].text"
                        :readonly="state.api.before[0].status"
                        :idd="'api_before_' + state.api.id"
                        @update:value="
                            (v) => {
                                if (state.api.before[0].text != v) {
                                    state.api.before[0].text = v
                                    saveApi()
                                }
                            }
                        "
                    >
                        <a-divider type="vertical" />
                        <a-switch
                            v-model:checked="state.api.before[0].status"
                            checked-children="自动沿用项目脚本"
                            un-checked-children="手动维护"
                            @change="saveApi()"
                        />

                        <a-button @click="getItemBefore()">获取项目前置</a-button>
                    </codeM>
                </div>
                <div v-if="state.params.select == '后置配置'" class="wh100">
                    <codeM
                        :value="state.api.after[0].text"
                        :readonly="state.api.after[0].status"
                        :idd="'api_after_' + state.api.id"
                        @update:value="
                            (v) => {
                                if (state.api.after[0].text != v) {
                                    state.api.after[0].text = v
                                    saveApi()
                                }
                            }
                        "
                    >
                        <a-divider type="vertical" />
                        <a-switch
                            v-model:checked="state.api.after[0].status"
                            checked-children="自动沿用项目脚本"
                            un-checked-children="手动维护"
                            @change="saveApi()"
                        />
                        <a-button @click="getItemAfter()">获取项目后置</a-button>
                    </codeM>
                </div>
            </div>
        </div>
        <div class="right_kuang f_col wh100" style="justify-content: flex-start">
            <div class="response-header">
                <div class="f_row" style="margin-top: 8px">
                    <a-segmented
                        v-model:value="state.responseTab"
                        :options="['请求信息', '响应信息', '响应头', '前置信息', '后置信息']"
                    />
                </div>
            </div>

            <div v-if="!state.response" class="empty-response f">
                <span>暂无响应数据</span>
            </div>

            <div v-else class="response-content">
                <!-- 请求信息 Tab -->
                <template v-if="state.responseTab === '请求信息'">
                    <div class="request-info">
                        <div class="info-header f_row">
                            <div class="f_row" style="gap: 16px">
                                <a-tag :color="getMethodColor(state.response.requestInfo.method)">
                                    {{ state.response.requestInfo.method }}
                                </a-tag>
                                <span class="info-value text-ellipsis">{{ state.response.requestInfo.url }}</span>
                            </div>
                            <a-button type="link" size="small" @click="copyRequestInfo"> 复制原始请求 </a-button>
                        </div>

                        <!-- 请求头信息 -->
                        <div class="info-section-title">Request Headers</div>
                        <div class="info-content">
                            <div
                                v-for="(value, key) in state.response.requestInfo.headers"
                                :key="key"
                                class="header-row"
                            >
                                <span class="header-name">{{ key }}:</span>
                                <span class="header-value">{{ value }}</span>
                            </div>
                        </div>

                        <!-- 请求体 -->
                        <template v-if="state.response.requestInfo.body">
                            <div class="info-section-title">Request Body</div>
                            <div class="info-content">
                                <json-editor-vue
                                    v-if="isJsonBody(state.response.requestInfo.body)"
                                    v-model="parsedRequestBody"
                                    :mode="'view'"
                                    :mode-list="['view']"
                                    :readonly="true"
                                    :language="'zh-CN'"
                                    class="mini-editor"
                                />
                                <pre v-else class="text-content">{{ state.response.requestInfo.body }}</pre>
                            </div>
                        </template>

                        <!-- cURL 命令 -->
                        <div class="info-section-title">
                            <span>cURL Command</span>
                            <div class="curl-command">
                                <a-button
                                    type="link"
                                    size="small"
                                    @click="copyToClipboard(generateCurlCommand())"
                                    class="copy-btn"
                                >
                                    复制 cURL
                                </a-button>
                            </div>
                        </div>
                        <div class="info-content">
                            <pre>{{ generateCurlCommand() }}</pre>
                        </div>
                    </div>
                </template>

                <!-- Response Tab -->
                <template v-if="state.responseTab === '响应信息'">
                    <div class="response-info">
                        <div class="info-header f_row">
                            <div class="f_row" style="gap: 16px">
                                <a-tag :color="getStatusColor(state.response.status)">
                                    {{ state.response.status.toUpperCase() }}
                                </a-tag>
                                <a-tag
                                    v-if="state.response.responseInfo"
                                    :color="getHttpStatusColor(state.response.responseInfo.status)"
                                >
                                    {{ state.response.responseInfo.status }}
                                    {{ state.response.responseInfo.statusText }}
                                </a-tag>
                                <a-tag color="blue">{{ state.response.duration }}ms</a-tag>
                            </div>
                            <a-button type="link" size="small" @click="copyResponseInfo"> 复制原始响应 </a-button>
                        </div>
                        <template v-if="state.response.status === 'success'">
                            <template v-if="state.response.responseInfo?.bodyInfo?.format === 'stream'">
                                <pre
                                    class="response-text stream-response"
                                    v-text="state.response.responseInfo.bodyText"
                                ></pre>
                            </template>
                            <template v-else>
                                <json-editor-vue
                                    v-if="isJsonResponse"
                                    v-model="state.response.responseInfo.body"
                                    :mode="'view'"
                                    :mode-list="['view']"
                                    :readonly="true"
                                    :language="'zh-CN'"
                                    class="response-body"
                                />
                                <pre v-else class="response-text" v-text="state.response.responseInfo.body"></pre>
                            </template>
                        </template>
                        <div v-else class="error-message">
                            {{ state.response.error?.message }}
                        </div>
                    </div>
                </template>

                <!-- Headers Tab -->
                <template v-if="state.responseTab === '响应头'">
                    <div class="headers-section">
                        <div class="headers-group">
                            <div class="headers-title f_row">
                                <span>Response Headers</span>
                                <a-button type="link" size="small" @click="copyRawHeaders('response')">
                                    复制原始内容
                                </a-button>
                            </div>
                            <div class="headers-container">
                                <div
                                    v-for="(value, key) in state.response.responseInfo?.headers"
                                    :key="key"
                                    class="header-item"
                                >
                                    <span class="header-name">{{ key }}</span>
                                    <span class="header-value">{{ value }}</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </template>

                <!-- 前置脚本 Tab -->
                <template v-if="state.responseTab === '前置信息'">
                    <div class="script-result">
                        <div class="script-header f_row">
                            <span class="script-title">执行结果</span>
                            <a-tag v-if="state.response?.beforeScript?.duration" color="blue">
                                {{ state.response.beforeScript.duration }}ms
                            </a-tag>
                        </div>
                        <div class="script-content">
                            <template v-if="state.response?.beforeScript?.logs?.length">
                                <div
                                    v-for="(log, index) in state.response.beforeScript.logs"
                                    :key="index"
                                    class="log-item"
                                    :class="log.type"
                                >
                                    <span class="log-time">{{ formatTime(log.time) }}</span>
                                    <span class="log-content">{{ log.content }}</span>
                                </div>
                            </template>
                            <div v-else class="empty-log">暂无执行记录</div>
                        </div>
                    </div>
                </template>

                <!-- 后置脚本 Tab -->
                <template v-if="state.responseTab === '后置信息'">
                    <div class="script-result">
                        <div class="script-header f_row">
                            <span class="script-title">执行结果</span>
                            <a-tag v-if="state.response?.afterScript?.duration" color="blue">
                                {{ state.response.afterScript.duration }}ms
                            </a-tag>
                        </div>
                        <div class="script-content">
                            <template v-if="state.response?.afterScript?.logs?.length">
                                <div
                                    v-for="(log, index) in state.response.afterScript.logs"
                                    :key="index"
                                    class="log-item"
                                    :class="log.type"
                                >
                                    <span class="log-time">{{ formatTime(log.time) }}</span>
                                    <span class="log-content">{{ log.content }}</span>
                                </div>
                            </template>
                            <div v-else class="empty-log">暂无执行记录</div>
                        </div>
                    </div>
                </template>
            </div>
        </div>
    </a-flex>
</template>
<script setup>
import { ref, onMounted, reactive, watch, inject, nextTick, h, computed } from "vue"
import { Store } from "@tauri-apps/plugin-store"
import { Info, Stretching, Magic } from "@icon-park/vue-next"
import { getUUID, debounce } from "@/utils/common"
import * as JSONEditor from "jsoneditor" //必须要的
import JsonEditorVue from "json-editor-vue3"
import codeM from "@/components/code.vue"
import { message } from "ant-design-vue"
import { enhancedFetch } from "@/utils/fetch-client"
import { mode } from "crypto-js"

let store = null
const globalVars = inject("globalVars")

const props = defineProps({
    data: Object,
})
const state = reactive({
    api: {},
    item: {},
    env: "",
    envData: {},
    ppp2: 100,
    loading: false,
    response: null,
    responseTab: "response",
    params: {
        select: "params",
        options: ["params", "headers", "body", "前置配置", "后置配置", "高级设置"],
        pSelectedRowKeys: [],
        hSelectedRowKeys: [],
        bSelectedRowKeys: [],
    },
    body: {
        select: "无",
        options: ["无", "json", "x-www-form-urlencoded", "form-data", "自定义"],
    },
})
const paramsColumns = [
    {
        title: "参数名",
        dataIndex: "name",
        align: "center",
        width: 200,
        fixed: "left",
    },
    {
        title: "参数值",
        dataIndex: "value",
        align: "center",
        width: 200,
    },
    {
        title: "编码",
        dataIndex: "isEncode",
        align: "center",
        width: 60,
    },
    {
        title: "必填",
        dataIndex: "isMust",
        align: "center",
        width: 60,
    },
    {
        title: "说明",
        dataIndex: "desc",
        align: "center",
        width: 200,
    },

    {
        title: "操作",
        dataIndex: "opt",
        align: "center",
        width: 60,
        fixed: "right",
    },
]
const headersColumns = [
    {
        title: "参数名",
        dataIndex: "name",
        align: "center",
    },
    {
        title: "参数值",
        dataIndex: "value",
        align: "center",
    },
    {
        title: "说明",
        dataIndex: "desc",
        align: "center",
    },
    {
        title: "操作",
        dataIndex: "opt",
        align: "center",
    },
]

function changeEnv() {
    saveApi()
    if (state.api.method == "POST") {
        state.params.select = "body"
    }
}
const ppp2Ref = ref(null)

const saveApi = debounce(() => {
    // console.log("save", state.api)
    store.set(`api_${state.item.id}_${state.api.id}`, { ...state.api })
    store.get(`item_${state.item.id}`).then((da) => {
        state.item = da
        for (let i = 0; i < state.item.apiList.length; i++) {
            if (state.item.apiList[i].id == state.api.id) {
                state.item.apiList[i] = state.api
                break
            }
        }
        store.set(`item_${state.item.id}`, state.item).then(() => {
            globalVars.changeItemId = state.item.id + "_a_" + new Date().getTime()
        })
    })
})
watch(
    () => globalVars.changeItemId,
    (a) => {
        if (a.indexOf("_a_") !== -1) {
            return
        }
        let tid = a.split("_")[0]
        if (tid == state.item.id) {
            store.get(`item_${state.item.id}`).then((da) => {
                state.item = da
                if (state.api.before[0].status) {
                    state.api.before[0].text = state.item.before[0].text || ""
                }
                if (state.api.after[0].status) {
                    state.api.after[0].text = state.item.after[0].text || ""
                }
            })
        }
    },
)

async function sendApi() {
    state.response = null
    state.loading = true
    try {
        let url = state.api.url
        if (url.indexOf("http") == -1 && state.envData.path) {
            url = state.envData.path + url
        }
        let method = state.api.method?.toUpperCase()
        const headers = {}

        // 处理请求头
        for (let i = 0; i < state.api.headers.length; i++) {
            if (state.api.headers[i].status && !state.api.headers[i].isInner) {
                headers[state.api.headers[i].name] = state.api.headers[i].value
            }
        }

        // 处理请求体
        let body = null
        if (state.api.body.select == "" || state.api.body.select == "无" || method == "GET") {
            body = null
        } else if (state.api.body.select == "json") {
            body = JSON.stringify(state.api.body.json)
            headers["Content-Type"] = "application/json"
        } else if (state.api.body.select == "x-www-form-urlencoded") {
            const formData = new URLSearchParams()
            for (let i = 0; i < state.api.body.form.length; i++) {
                if (state.api.body.form[i].status && !state.api.body.form[i].isInner) {
                    formData.append(state.api.body.form[i].name, state.api.body.form[i].value)
                }
            }
            body = formData.toString()
            headers["Content-Type"] = "application/x-www-form-urlencoded"
        } else if (state.api.body.select == "form-data") {
            const formData = new FormData()
            for (let i = 0; i < state.api.body.form.length; i++) {
                if (state.api.body.form[i].status && !state.api.body.form[i].isInner) {
                    formData.append(state.api.body.form[i].name, state.api.body.form[i].value)
                }
            }
            body = formData
            // FormData会自动设置正确的Content-Type，所以这里不需要手动设置
        } else if (state.api.body.select == "自定义") {
            body = state.api.body.text
        }

        const response = await enhancedFetch(url, {
            method,
            headers,
            body,
            redirect: "manual",
            timeout: 100000,
        })
        state.responseTab = "响应信息"

        state.response = response
        state.response.responseInfo.bodyText = ""
        state.response.responseInfo.list = []
        state.response.responseInfo.index = -1

        console.log(response, new Date().getTime())
        // 处理响应
        if (response.status === "error" || response.status === "timeout") {
            state.response = {
                status: response.status,
                requestInfo: response.requestInfo,
                error: response.error,
                duration: response.duration,
                responseInfo: {
                    body: response.error.message,
                    bodyText: response.error.message,
                    bodyInfo: {
                        format: "text",
                    },
                    headers: {},
                    ok: false,
                    status: 0,
                    statusText: response.error.message,
                },
            }

            return
        }

        if (response.status === "success" && response.responseInfo?.bodyInfo?.format === "stream") {
            try {
                // 确保响应体存在
                if (!response.responseInfo.body) {
                    throw new Error("No response body available")
                }

                // 初始化响应文本
                state.response.responseInfo.bodyText = ""

                // 获取响应流的读取器
                const reader = response.responseInfo.body.getReader()

                // 处理流数据
                const processStream = async () => {
                    try {
                        while (true) {
                            const { done, value } = await reader.read()

                            if (done) break

                            // value 已经是一行完整的文本了
                            await processStreamLine(value)
                            // 添加适当的延迟，使显示更平滑
                            await new Promise((resolve) => setTimeout(resolve, 10))
                        }
                    } catch (error) {
                        console.error("Error processing stream:", error)
                        throw error
                    }
                }
                // 开始处理流
                await processStream()
            } catch (error) {
                console.error("Stream processing error:", error)
                message.error("处理流式数据时发生错误：" + error.message)
            }
        }
    } catch (error) {
        message.error("请求发送失败：" + error.message)
        console.error("请求发送失败：", error)
        state.response = null
    } finally {
        state.loading = false
    }
}

// 处理流式响应的单行数据
async function processStreamLine(line) {
    try {
        let formattedLine
        // 尝试解析 JSON
        try {
            const jsonData = JSON.parse(line)
            // 只有当内容确实是格式化的JSON时才添加换行
            if (typeof jsonData === "object" && jsonData !== null) {
                formattedLine = JSON.stringify(jsonData, null, 2)
            } else {
                formattedLine = line
            }
        } catch {
            // 如果不是 JSON，保持原始文本，移除多余的换行
            formattedLine = line.trim()
        }

        // 只在非空内容时添加新行
        if (formattedLine) {
            // 如果已经有内容，添加换行符
            // if (state.response.responseInfo.bodyText) {
            //     state.response.responseInfo.bodyText += "\n"
            // }
            state.response.responseInfo.list.push(formattedLine)
            state.response.responseInfo.bodyText += formattedLine
        }

        // 使用 nextTick 确保 DOM 更新后再滚动
        await nextTick()
        const responseElement = document.querySelector(".stream-response")
        if (responseElement) {
            responseElement.scrollTo({
                top: responseElement.scrollHeight,
                behavior: "smooth",
            })
        }
    } catch (error) {
        console.error("Error processing stream line:", error)
    }
}
const isJsonResponse = computed(() => {
    return state.response?.responseInfo?.bodyInfo?.format === "json"
})

function changeBodyType() {
    saveApi()
}

const parsedRequestBody = computed(() => {
    if (!state.response?.requestInfo.body) return null
    try {
        return JSON.parse(state.response.requestInfo.body)
    } catch {
        return state.response.requestInfo.body
    }
})

function isJsonBody(body) {
    try {
        JSON.parse(body)
        return true
    } catch {
        return false
    }
}

function getMethodColor(method) {
    const colors = {
        GET: "green",
        POST: "blue",
        PUT: "orange",
        DELETE: "red",
    }
    return colors[method] || "default"
}

function getStatusColor(status) {
    const colors = {
        success: "success",
        error: "error",
        timeout: "warning",
    }
    return colors[status] || "default"
}

function getHttpStatusColor(status) {
    if (status >= 200 && status < 300) return "success"
    if (status >= 300 && status < 400) return "warning"
    if (status >= 400) return "error"
    return "default"
}

function formatTime(timestamp) {
    const date = new Date(timestamp)
    return date.toLocaleTimeString("zh-CN", {
        hour12: false,
        hour: "2-digit",
        minute: "2-digit",
        second: "2-digit",
        fractionalSecondDigits: 3,
    })
}

function copyRawHeaders(type) {
    if (!state.response) return

    const headers = type === "request" ? state.response.requestInfo?.headers : state.response.responseInfo?.headers

    if (!headers) return

    const rawHeaders = Object.entries(headers)
        .map(([key, value]) => `${key}: ${value}`)
        .join("\n")

    copyToClipboard(rawHeaders)
}

function copyRequestInfo() {
    if (!state.response?.requestInfo) return

    const { method, url, headers, body } = state.response.requestInfo
    let rawRequest = `${method} ${url}\n`

    // 添加请求头
    rawRequest += Object.entries(headers)
        .map(([key, value]) => `${key}: ${value}`)
        .join("\n")

    // 添加请求体
    if (body) {
        rawRequest += "\n\n" + (typeof body === "string" ? body : JSON.stringify(body, null, 2))
    }

    copyToClipboard(rawRequest)
}

function copyResponseInfo() {
    if (!state.response?.responseInfo) return

    const { status, statusText, headers, body } = state.response.responseInfo
    let rawResponse = `HTTP/1.1 ${status} ${statusText}\n`

    // 添加响应头
    rawResponse += Object.entries(headers)
        .map(([key, value]) => `${key}: ${value}`)
        .join("\n")

    // 添加响应体
    if (body) {
        rawResponse += "\n\n" + (typeof body === "object" ? JSON.stringify(body, null, 2) : body)
    }

    copyToClipboard(rawResponse)
}

function generateCurlCommand() {
    if (!state.response?.requestInfo) return ""

    const { url, method, headers, body } = state.response.requestInfo
    let curl = `curl -X ${method} '${url}'`

    // 添加请求头
    Object.entries(headers).forEach(([key, value]) => {
        curl += `\n  -H '${key}: ${value}'`
    })

    // 添加请求体
    if (body) {
        curl += `\n  -d '${typeof body === "string" ? body : JSON.stringify(body)}'`
    }

    return curl
}

async function copyToClipboard(text) {
    try {
        await navigator.clipboard.writeText(text)
        message.success("已复制到剪贴板")
    } catch (err) {
        message.error("复制失败")
    }
}

async function getItemBefore() {
    // const da = await store.get(`item_${state.item.id}`)
    state.api.before[0].text = state.item.before[0].text || ""
    message.success("已覆盖更新")
    if (!state.api.before[0].status) {
        saveApi()
    }
}

async function getItemAfter() {
    // const da = await store.get(`item_${state.item.id}`)
    state.api.after[0].text = state.item.after[0].text || ""
    message.success("已覆盖更新")
    if (!state.api.after[0].status) {
        saveApi()
    }
}

function onSelectHeadersChange(keys) {
    if (keys.indexOf("") == -1) {
        state.params.hSelectedRowKeys.push("")
    }
    state.params.hSelectedRowKeys = keys
    for (let i = 0; i < state.api.headers.length; i++) {
        if (keys.indexOf(state.api.headers[i].key) != -1) {
            state.api.headers[i].status = true
        } else {
            state.api.headers[i].status = false
        }
    }
    saveApi()
}
function onSelectBodyChange(keys) {
    if (keys.indexOf("") == -1) {
        state.params.bSelectedRowKeys.push("")
    }
    state.params.bSelectedRowKeys = keys
    for (let i = 0; i < state.api.body.form.length; i++) {
        if (keys.indexOf(state.api.body.form[i].key) != -1) {
            state.api.body.form[i].status = true
        } else {
            state.api.body.form[i].status = false
        }
    }
    saveApi()
}
function onSelectChange(pSelectedRowKeys) {
    if (pSelectedRowKeys.indexOf("") == -1) {
        state.params.pSelectedRowKeys.push("")
    }
    state.params.pSelectedRowKeys = pSelectedRowKeys
    for (let i = 0; i < state.api.params.length; i++) {
        if (pSelectedRowKeys.indexOf(state.api.params[i].key) != -1) {
            state.api.params[i].status = true
        } else {
            state.api.params[i].status = false
        }
    }
    changeUrl()
    saveApi()
}
const changeUrl = debounce(() => {
    let params = ""
    for (let i = 0; i < state.api.params.length; i++) {
        if (state.api.params[i].status && state.api.params[i].name) {
            if (state.api.params[i].isEncode) {
                params += `${state.api.params[i].name}=${encodeURIComponent(state.api.params[i].value)}&`
            } else {
                params += `${state.api.params[i].name}=${state.api.params[i].value}&`
            }
        }
    }
    if (params != "") {
        params = "?" + params.slice(0, -1)
    }
    state.api.url = `${state.api.path}${params}`
})
function changeHeaders(key, record) {
    if (record.isInner && key != "delete") {
        record.isInner = false
        record.status = true
        record.isEncode = true
        state.api.headers.push({
            status: false,
            key: getUUID(),
            name: "",
            value: "",
            desc: "",
            isMust: false,
            isInner: true,
            isEncode: false,
        })
        if (state.params.hSelectedRowKeys.indexOf(record.key) == -1) {
            state.params.hSelectedRowKeys.push(record.key)
        }
    }
    if (key == "delete") {
        state.api.headers = state.api.headers.filter((item) => item.key != record.key)
    }
    saveApi()
}
function changeBody(key, record) {
    if (record.isInner && key != "delete") {
        record.isInner = false
        record.status = true
        if (state.api.body.select == "x-www-form-urlencoded") {
            record.isEncode = true
        } else {
            record.isEncode = false
        }
        state.api.body.form.push({
            status: false,
            key: getUUID(),
            name: "",
            value: "",
            desc: "",
            isMust: false,
            isInner: true,
            isEncode: false,
        })
        if (state.params.bSelectedRowKeys.indexOf(record.key) == -1) {
            state.params.bSelectedRowKeys.push(record.key)
        }
    }
    if (key == "delete") {
        state.api.body.form = state.api.body.form.filter((item) => item.key != record.key)
    }
    saveApi()
}
function changeparams(key, record) {
    if (record.isInner && key != "delete") {
        record.isInner = false
        record.status = true
        record.isEncode = true
        state.api.params.push({
            status: false,
            key: getUUID(),
            name: "",
            value: "",
            desc: "",
            isMust: false,
            isInner: true,
            isEncode: false,
        })
        if (state.params.pSelectedRowKeys.indexOf(record.key) == -1) {
            state.params.pSelectedRowKeys.push(record.key)
        }
    }
    if (key == "delete") {
        state.api.params = state.api.params.filter((item) => item.key != record.key)
    }
    changeUrl()
    saveApi()
}
function getEnv() {
    for (let i = 0; i < state.item.env.all.length; i++) {
        if (state.item.env.all[i].value == state.env) {
            state.envData = state.item.env.all[i]
        }
    }
}
function initApi() {
    state.api.params = state.api.params || [
        { status: false, key: getUUID(), name: "", value: "", desc: "", isMust: false, isInner: true, isEncode: false },
    ]
    //移除全局参数
    state.api.params = state.api.params.filter((item) => !item.global)
    // 添加全局参数
    for (let i = 0; i < state.item.global.params.length; i++) {
        let p = state.item.global.params[i]
        if (p.isInner) {
            continue
        }
        //插入到第一个

        state.api.params.unshift({
            ...p,
            global: true,
        })
    }
    state.api.headers = state.api.headers || [
        { status: false, key: getUUID(), name: "", value: "", desc: "", isMust: false, isInner: true, isEncode: false },
    ]
    //移除全局参数
    state.api.headers = state.api.headers.filter((item) => !item.global)
    // 添加全局参数
    for (let i = 0; i < state.item.global.headers.length; i++) {
        let p = state.item.global.headers[i]
        if (p.isInner) {
            continue
        }
        state.api.headers.unshift({
            ...p,
            global: true,
        })
    }
    state.api.body = state.api.body || {
        select: "无",
        json: {},
        form: [
            {
                status: false,
                key: getUUID(),
                name: "",
                value: "",
                desc: "",
                isMust: false,
                isInner: true,
                isEncode: false,
            },
        ],
        text: "",
    }
    //移除全局参数
    state.api.body.form = state.api.body.form.filter((item) => !item.global)
    // 添加全局参数
    for (let i = 0; i < state.item.global.body.length; i++) {
        let p = state.item.global.body[i]
        if (p.isInner) {
            continue
        }
        state.api.body.form.unshift({
            ...p,
            global: true,
        })
    }
    // 选中状态
    for (let i = 0; i < state.api.params.length; i++) {
        if (state.api.params[i].status) {
            state.params.pSelectedRowKeys.push(state.api.params[i].key)
        }
    }
    for (let i = 0; i < state.api.headers.length; i++) {
        if (state.api.headers[i].status) {
            state.params.hSelectedRowKeys.push(state.api.headers[i].key)
        }
    }
    for (let i = 0; i < state.api.body.form.length; i++) {
        if (state.api.body.form[i].status) {
            state.params.bSelectedRowKeys.push(state.api.body.form[i].key)
        }
    }
    //前置后置
    state.api.before = state.api.before || [
        {
            status: true,
            text: "",
        },
    ]

    if (state.api.before[0].status) {
        state.api.before[0].text = state.item.before[0].text || ""
    }
    state.api.after = state.api.after || [
        {
            status: true,
            text: "",
        },
    ]
    if (state.api.after[0].status) {
        state.api.after[0].text = state.item.after[0].text || ""
    }
    if (state.api.method == "POST") {
        state.params.select = "body"
    }
    console.log(state.api)
}
function initUrl() {
    if (!state.api.path) {
        state.api.path = "/"
    }
    changeUrl()
}
onMounted(async () => {
    store = await Store.get("store.json")
    state.api = props.data.api
    state.item = props.data.item
    console.log(state.item)
    nextTick(() => {
        try {
            state.ppp2 = ppp2Ref.value?.offsetHeight - 70
        } catch (error) {}
    })

    if (state.api && state.api.id) {
        const da = await store.get(`api_${state.item.id}_${state.api.id}`)
        state.api = da
    }
    initApi()
    state.env = state.item.env.default.value
    state.envData = state.item.env.default
    initUrl()
    window.addEventListener("resize", () => {
        state.ppp2 = ppp2Ref.value?.offsetHeight - 70
    })
})
watch(
    () => props.data,
    () => {
        if (!props.data?.api?.id || !props.data?.item?.id) return
        state.api = props.data.api
        state.item = props.data.item
    },
)
function refreshItem() {
    store.get(`item_${state.item.id}`).then((da) => {
        state.item = da
        message.success("已刷新")
    })
}
</script>
<style scoped>
:where(.api_info) {
    flex-wrap: wrap;
    overflow: hidden !important;
    background-color: var(--Neutral-11) !important;
}

:where(.left_kuang),
:where(.right_kuang) {
    flex: 1 1 calc(50% - 10px);
    min-width: 480px;
    height: 100%;
    padding: 24px;
    background: var(--Neutral-12);
    border-radius: 12px;
    border: 1px solid var(--Neutral-9);
    max-width: 888px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

@media screen and (max-width: 960px) {
    .left-section,
    .right-section {
        flex: 1 1 100%;
    }
}

:where(.button_row) {
    justify-content: flex-start !important;
    margin-bottom: 20px;
    gap: 12px;
    padding: 0 16px;

    border-radius: 8px;
}

:where(.path) {
    margin-bottom: 20px;
}

:where(.path_input) {
    word-break: break-all;
    font-family: monospace;
    background-color: var(--Neutral-11);
    border-color: var(--Neutral-10);
    border-radius: 8px;
    padding: 12px;
}

:where(.path_input:hover) {
    border-color: var(--Neutral-9);
}

:where(.path_input:focus) {
    border-color: var(--Geek-Blue-5);
    box-shadow: 0 0 0 2px rgba(89, 126, 247, 0.1);
}

:where(.ppp) {
    margin: 20px 0;
    width: 100%;
}

:where(.ppp2) {
    border-radius: 8px;
    padding-bottom: 8px;
}

:where(.bodySegmented) {
    border-top: 1px solid var(--Neutral-9);
    margin-bottom: 16px;
}

:deep(.ant-select-selector) {
    background-color: var(--Neutral-11) !important;
    border-color: var(--Neutral-10) !important;
}

:deep(.ant-select:hover .ant-select-selector) {
    border-color: var(--Neutral-9) !important;
}

:deep(.ant-segmented) {
    background-color: var(--Neutral-11);
}

:deep(.ant-segmented-item-selected) {
    background-color: var(--Neutral-12);
    color: var(--character-85);
}

:deep(.ant-table) {
    background-color: transparent;
}
/* :deep(.ant-table) {
    border: 1px solid var(--Neutral-9);
    border-radius: 4px;
} */

:deep(.ant-table-cell) {
    background-color: var(--Neutral-11) !important;
    border: 1px solid var(--Neutral-9) !important;
    padding: 4px !important;
}

:deep(.ant-input) {
    background-color: var(--Neutral-11);
    border: 1px solid var(--Neutral-9);
    border-radius: 2px;
}

:deep(.ant-input:hover) {
    border-color: var(--Neutral-8);
}

:deep(.ant-input:focus) {
    border-color: var(--Geek-Blue-5);
}

/* :deep(.ant-table-row) {
    border-bottom: 1px solid var(--Neutral-9);
} */

:deep(.ant-table-row:last-child) {
    border-bottom: none;
}

:deep(.ant-checkbox-wrapper) {
    margin-left: 4px;
}

.response-header {
    padding: 12px 16px;
    border-bottom: 1px solid var(--Neutral-9);
    width: 100%;
    border-radius: 6px 6px 0 0;
    margin-bottom: 1px;
}

.status-bar {
    gap: 12px;
    align-items: center;
    margin-bottom: 12px;
}

.empty-response {
    flex-direction: column;
    gap: 12px;
    color: var(--character-60);
    height: 200px;
    font-size: 14px;
}

.response-content {
    height: 100%;
    overflow: auto;
    width: 100%;
}

.request-info {
    font-size: 14px;
    width: 100%;
}

.info-header {
    padding: 12px 16px;
    background: var(--Neutral-11);
    border-radius: 6px;
    margin-bottom: 16px;
    justify-content: space-between;
    align-items: center;
    border: 1px solid var(--Neutral-9);
}

.response-info {
    height: 100%;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.response-body {
    flex: 1;
    min-height: 200px;
}

.info-value {
    flex: 1;
    color: var(--character-85);
}

.info-section-title {
    font-weight: 500;
    margin: 16px 0 8px;
    color: var(--character-85);
    font-size: 14px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.info-content {
    border: 1px solid var(--Neutral-9);
    border-radius: 6px;
    background: var(--Neutral-11);
    padding: 12px;
    margin: 8px 0;
}

.header-row {
    padding: 8px 12px;
    border-bottom: 1px solid var(--Neutral-8);
    font-size: 14px;
}

.header-row:last-child {
    border-bottom: none;
}

.header-name {
    color: var(--character-60);
    margin-right: 8px;
    font-weight: 500;
}

.header-value {
    color: var(--character-85);
    word-break: break-all;
}

.curl-command {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.curl-command pre {
    margin: 0;
    padding: 12px;
    white-space: pre-wrap;
    word-break: break-all;
    font-size: 14px;
    font-family: monospace;
    background: var(--Neutral-11);
    border: 1px solid var(--Neutral-9);
    border-radius: 4px;
}

.copy-btn {
    white-space: nowrap;
}

.mini-editor {
    height: 440px;
}

.text-content {
    padding: 12px;
    margin: 0;
    max-height: 240px;
    overflow: auto;
    font-size: 14px;
    white-space: pre-wrap;
    word-break: break-all;
}

.response-body {
    height: 100%;
    border: 1px solid var(--Neutral-8);
    border-radius: 4px;
}

.response-text {
    padding: 12px;
    margin: 0;
    background: var(--Neutral-10);
    border-radius: 4px;
    white-space: pre-wrap;
    word-break: break-word;
    font-size: 14px;
    font-family: "Menlo", Consolas, monospace;
    line-height: 1.6;
    tab-size: 4;
}

.stream-response {
    max-height: 500px;
    overflow-y: auto;
    background: var(--Neutral-11);
    border: 1px solid var(--Neutral-9);
    padding: 16px;
}

.stream-response::-webkit-scrollbar {
    width: 8px;
}

.stream-response::-webkit-scrollbar-track {
    background: var(--Neutral-11);
}

.stream-response::-webkit-scrollbar-thumb {
    background: var(--Neutral-8);
    border-radius: 4px;
}

.error-message {
    color: var(--Error-6);
    padding: 12px;
    background: var(--Error-1);
    border-radius: 4px;
    font-size: 14px;
}

.headers-section {
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.headers-group {
    border: 1px solid var(--Neutral-9);
    border-radius: 6px;
    background: var(--Neutral-11);
    margin-bottom: 16px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.headers-title {
    padding: 12px;
    font-weight: 500;
    background: var(--Neutral-10);
    border-bottom: 1px solid var(--Neutral-8);
    justify-content: space-between;
}

.headers-container {
    font-size: 14px;
    padding: 8px 0;
    min-height: 80px;
}

.headers-container:empty::after {
    content: "暂无响应头信息";
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100%;
    color: var(--character-45);
    font-size: 14px;
    margin-top: 20px;
}

.header-item {
    padding: 8px 12px;
    display: grid;
    grid-template-columns: 200px 1fr;
    gap: 16px;
    border-bottom: 1px solid var(--Neutral-8);
}

.header-item:last-child {
    border-bottom: none;
}

.header-name {
    color: var(--character-60);
    font-weight: 500;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.header-value {
    color: var(--character-85);
    word-break: break-all;
}

.script-result {
    border: 1px solid var(--Neutral-9);
    border-radius: 6px;
    background: var(--Neutral-11);
    overflow: hidden;
}

.script-header {
    padding: 12px;
    background: var(--Neutral-10);
    border-bottom: 1px solid var(--Neutral-8);
    justify-content: space-between;
}

.script-title {
    font-weight: 500;
}

.script-content {
    padding: 12px;
    max-height: 500px;
    overflow: auto;
}

.log-item {
    padding: 8px 12px;
    font-family: "Menlo", "Monaco", "Courier New", monospace;
    display: flex;
    gap: 12px;
    font-size: 13px;
    border-bottom: 1px solid var(--Neutral-10);
    background: var(--Neutral-12);
}

.log-item:last-child {
    border-bottom: none;
}

.log-item:hover {
    background: var(--Neutral-11);
}

.log-item.error {
    color: var(--Error-6);
    background: var(--Error-1);
}

.log-item.warn {
    color: var(--Warning-6);
    background: var(--Warning-1);
}

.log-time {
    color: var(--character-45);
    white-space: nowrap;
}

.empty-log {
    color: var(--character-45);
    text-align: center;
    padding: 24px;
}

.text-ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
</style>
<style>
.ppp2 .ant-table-cell {
    padding: 0px;
}
.ppp2 .ant-table-cell input,
.ppp2 .ant-input-affix-wrapper {
    border-radius: 0;
}
/* 移除表格的弹簧效果 */
.ppp2 .ant-table-body {
    -webkit-overflow-scrolling: auto !important;
    overscroll-behavior: none;
}

.ant-table-body {
    -webkit-overflow-scrolling: auto !important;
    overscroll-behavior: none;
}

.response-content {
    -webkit-overflow-scrolling: auto !important;
    overscroll-behavior: none;
}
</style>
